package top.lingkang.finalsecurity.solonplugin;

import org.noear.solon.core.AppContext;
import org.noear.solon.core.BeanWrap;
import org.noear.solon.core.Plugin;
import org.noear.solon.core.event.AppLoadEndEvent;
import org.noear.solon.core.handle.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.NOPLogger;
import top.lingkang.finalsecurity.common.annotation.FinalCheck;
import top.lingkang.finalsecurity.common.annotation.FinalCheckLogin;
import top.lingkang.finalsecurity.common.base.FinalHttpProperties;
import top.lingkang.finalsecurity.solonplugin.interceptor.FinalCheckAnnotation;
import top.lingkang.finalsecurity.solonplugin.interceptor.FinalCheckLoginAnnotation;
import top.lingkang.finalsecurity.solonplugin.config.FinalSecurityConfiguration;

import java.util.List;

/**
 * solon 初始化插件
 *
 * @author lingkang
 * Created by 2022/10/28
 * @since 3.0.0
 */
public class FinalSecurityPlugin implements Plugin {
    private static final Logger log = LoggerFactory.getLogger(FinalSecurityPlugin.class);

    @Override
    public void start(AppContext context) {
        log.info("final-security 开始配置");
        // 注册bean
        context.beanRegister(new BeanWrap(context, FinalSecurityHolder.class, new FinalSecurityHolder()), null, true);

        // 手动注册注解
        context.beanInterceptorAdd(FinalCheck.class, new FinalCheckAnnotation());
        context.beanInterceptorAdd(FinalCheckLogin.class, new FinalCheckLoginAnnotation());

        context.onEvent(AppLoadEndEvent.class, appLoadEndEvent -> {
            AppContext appContext = appLoadEndEvent.context();
            FinalHttpProperties properties = null;
            List<Filter> beansOfType = appContext.getBeansOfType(Filter.class);
            for (Filter filter : beansOfType) {
                if (FinalSecurityConfiguration.class.isAssignableFrom(filter.getClass())) {
                    FinalSecurityConfiguration configuration = (FinalSecurityConfiguration) filter;
                    configuration.init();
                    properties = configuration.getProperties();
                    // 将配置注册到上下文中
                    context.beanRegister(new BeanWrap(context, FinalHttpProperties.class, properties), null, true);
                    break;
                }
            }
            if (properties != null) {
                FinalCheckAnnotation finalCheckAnnotation = (FinalCheckAnnotation) appContext.beanInterceptorGet(FinalCheck.class).getReal();
                finalCheckAnnotation.properties = properties;
                FinalCheckLoginAnnotation loginAnnotation = (FinalCheckLoginAnnotation) appContext.beanInterceptorGet(FinalCheckLogin.class).getReal();
                loginAnnotation.properties = properties;
            } else {
                if (NOPLogger.class.isAssignableFrom(log.getClass())) {
                    System.err.println("警告，您还未配置 final-security ，安全认证未开启！");
                } else {
                    log.warn("警告，您还未配置 final-security ，安全认证未开启！");
                }
            }
            log.info("final-security 配置完成");
        });
    }
}
